home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 010 / aliens.arc / ALIENS.C
Encoding:
C/C++ Source or Header  |  1980-01-01  |  34.0 KB  |  1,160 lines

  1. /*
  2.  * Aliens -- an animated video game
  3.  *      the original version is from 
  4.  *      Fall 1979                       Cambridge               Jude Miller
  5.  *
  6.  * Score keeping modified by Rob Cohen, BTL, June 1980.
  7.  *
  8.  * Concept of levels introduced, bugs fixed, point penalties added
  9.  * by Alex Podlecki, WECo, 81-82.
  10.  */
  11.  
  12. #include <pwd.h>
  13. #include <termio.h>
  14. #include <fcntl.h>
  15. #include <stdio.h>
  16. #include <ctype.h>
  17.  
  18. /* defines */
  19.  
  20. #define SCOREFILE "/usr/games/lib/aliens.hscores"
  21. #define LOGFILE "/usr/games/lib/aliens.log"
  22. #define LEFT ','
  23. #define LLEFT 'z'
  24. #define RIGHT '/'
  25. #define LRIGHT 'c'
  26. #define HALT '.'
  27. #define LHALT 'x'
  28. #define FIRE ' '
  29. #define DELETE '\177'
  30. #define ABORT '\34'
  31. #define QUIT 'q'
  32. #define PAUSE '\23'
  33. #define QQUIT '\3'
  34. #define GAME1 '1'
  35. #define GAME2 '2'
  36. #define GAME3 '3'
  37. #define GAME4 '4'
  38. #define GAME5 '5'
  39. #define GAME6 '6'
  40. #define BOMB_MAX 10
  41. #define BOMB_ROW 20
  42. #define MINCOL 1
  43. #define SCORESIZE (sizeof (scorsave))
  44. #define HP2621 1
  45. #define ADM3 2
  46. #define VT100 3
  47. #define TTY4424 4
  48. #define Z19 5
  49. #define OVERUN 10
  50. #define DEATH 25
  51.  
  52. /* global variables */
  53.  
  54. int scores = 0,bases,game;
  55. int i,j,danger,max_danger;
  56. int flip,flop,left,al_num,b;
  57. int al_cnt, bmb_cnt=0, bmb_max, spread;
  58. int slow = 0;
  59. int term_type = 0, level = 0;
  60. int scorefile;
  61. char combuf[2];
  62. int ttyin;
  63. char *ttydev;
  64. struct termio ttyorig,ttyjunk;
  65. extern char *ttyname();
  66. long timein;
  67. int barrinit[4][81] = {
  68. {0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,
  69. 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,
  70. 0,0,0,0,0,0,0,0,0},
  71. {0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,
  72. 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,
  73. 0,0,0,0,0,0,0,0},
  74. {0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,
  75. 0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,
  76. 0,0,0,0,0,0,0,0},
  77. {0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,
  78. 0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,1,1,1,
  79. 0,0,0,0,0,0,0,0}
  80. };
  81. int barr[4][81];
  82. struct
  83. {
  84.         int row;
  85.         int col;
  86. }
  87. al[55];
  88. struct {
  89.         int row;
  90.         int col;
  91.         int vel;
  92. } bas;
  93. struct {
  94.         int row;
  95.         int col;
  96. } bem;
  97. struct {
  98.         int row;
  99.         int col;
  100. }bmb[BOMB_MAX];
  101. struct {
  102.         int val;
  103.         int col;
  104.         int vel;
  105. }shp;
  106. struct {
  107.         long hscr;
  108.         short hid;
  109.         long sscr;
  110.         short sid;
  111. } scorsave[6] = {
  112.         {0,0,0,0},
  113.         {0,0,0,0},
  114.         {0,0,0,0},
  115.         {0,0,0,0},
  116.         {0,0,0,0},
  117.         {0,0,0,0}
  118. };
  119.  
  120. /*
  121.  * main -- scheduler and main entry point for aliens
  122.  */
  123.  
  124. main(argc,argv)
  125. int argc;
  126. char *argv[];
  127. {
  128.         char *getenv();
  129.  
  130.         ttydev = getenv("TERM");
  131.         if (ttydev)
  132.                 {
  133.                         switch (*ttydev)
  134.                         {
  135.                         case '2':
  136.                                 term_type = HP2621;
  137.                                 break;
  138.                         case 'a':
  139.                                 term_type = ADM3;
  140.                                 break;
  141.                         case 'v':
  142.                                 term_type = VT100;
  143.                                 break;
  144.                         case '4':
  145.                                 term_type = TTY4424;
  146.                                 break;
  147.                         case 'z':
  148.                         case 'g':
  149.                                 term_type = Z19;
  150.                                 break;
  151.                         }
  152.                 }
  153.         for ( i = 1; i < argc; i++ )
  154.         switch ( argv[i][0] )
  155.         {
  156.         case '-':
  157.                 switch ( argv[i][1] )
  158.                 {
  159.                 case 'T':
  160.                         switch ( argv[i][2] )
  161.                         {
  162.                         case '2':
  163.                                 term_type = HP2621;
  164.                                 break;
  165.                         case 'a':
  166.                                 term_type = ADM3;
  167.                                 break;
  168.                         case 'v':
  169.                                 term_type = VT100;
  170.                                 break;
  171.                         case '4':
  172.                                 term_type = TTY4424;
  173.                                 break;
  174.                         case 'z':
  175.                         case 'g':
  176.                                 term_type = Z19;
  177.                                 break;
  178.                         default:
  179.                                 usage();
  180.                                 break;
  181.                         }
  182.                         break;
  183.                 case 'l':
  184.                         if ( isdigit(level=argv[i][2]) == 0 )
  185.                                 usage();
  186.                         level -= '0';
  187.                         break;
  188.                 case 's':
  189.                         alhs();
  190.                         break;
  191.                 default:
  192.                         usage();
  193.                         break;
  194.                 }
  195.                 break;
  196.         default:
  197.                 usage();
  198.                 break;
  199.         }
  200.         if ( term_type == 0 )
  201.                 usage();
  202.         init();
  203.         while (1)
  204.         {
  205.                 tabl();
  206.                 while (1)
  207.                 {
  208.                         poll();
  209.                         beam();
  210.                         beam();
  211.                         beam();
  212.                         base();
  213.                         bomb();
  214.                         ship();
  215.                         if ( game != 4 ) alien();
  216.                         if ( game == 2 ) alien();
  217.                         alien();
  218.                         if ((al_cnt == 0) && (bmb_cnt == 0)) break;
  219.                 };
  220.                 gauntlet();
  221.         };
  222. }
  223.  
  224. /*
  225.  * usage -- error message for incorrect usage
  226.  */
  227.  
  228. usage()
  229. {
  230.         (void) printf(" Usage: aliens -Tname -ldigit -s\n");
  231.         (void) printf(" where name is one of the following terminal types\n");
  232.         (void) printf("       2621 adm3 vt100 z19 4424\n");
  233.         (void) printf(" digit is the level of difficulty from 0 to 9\n");
  234.         (void) printf("       level 0 is the easiest and is the default\n");
  235.         (void) printf(" and the s option only lists high scores\n");
  236.         exit(1);
  237. }
  238.  
  239. /*
  240.  * init -- does global initialization
  241.  */
  242.  
  243. init()
  244. {
  245.         extern long time();
  246.         int btemp;
  247.  
  248.         (void) time(&timein);  /* get start time */
  249.         srand((unsigned) timein);  /* start rand randomly */
  250.  
  251.         /* do terminal dependent initialization */
  252.  
  253.         switch ( term_type )
  254.         {
  255.         case VT100:
  256.                 (void) printf("\033<"); /* set ANSI mode */
  257.                 break;
  258.         case TTY4424:
  259.                 (void) printf("\033[20l"); /* set line feed only for new line */
  260.                 break;
  261.         default:
  262.                 break;
  263.         }
  264.  
  265.         /* setup raw mode, no echo */
  266.  
  267.         if ((ttydev = ttyname(0)) == NULL) {
  268.                 (void) printf("Cannot find terminal\n");
  269.                 exit(-1);
  270.         }
  271.         if ((ttyin = open(ttydev,O_RDWR|O_NDELAY)) == -1) {
  272.                 (void) printf("Cannot open %s\n",ttydev);
  273.                 exit(-1);
  274.         }
  275.         (void) ioctl(ttyin,TCGETA,&ttyorig);
  276.         ttyjunk = ttyorig;
  277.         ttyjunk.c_lflag &= ~(ICANON|ECHO|ISIG);
  278.         ttyjunk.c_oflag &= ~ONLCR;
  279.         ttyjunk.c_iflag &= ~IXON;
  280.         ttyjunk.c_cc[VMIN] = 1;
  281.         ttyjunk.c_cc[VTIME] = 1;
  282.         btemp = ttyjunk.c_cflag & CBAUD;
  283.  
  284.         /* determine low speed terminal penalty factor */
  285.  
  286.         if ( btemp <= B4800 ) slow++;
  287.         if ( btemp <= B2400 ) slow++;
  288.         if ( btemp <= B1200 ) slow++;
  289.  
  290.         (void) ioctl(ttyin,TCSETAW,&ttyjunk);
  291.  
  292.         /* new game starts here */
  293.  
  294.         game = 0;
  295.         instruct();
  296.         while (game==0) poll();
  297.         scores = 0;
  298.         bases = 3;
  299.         max_danger = 22;
  300.         return;
  301. };
  302.  
  303. /*
  304.  * instructions -- print out instructions
  305.  */
  306.  
  307. instruct() {
  308.         clr();
  309.         pos(0,0);
  310.         (void) printf("Attention: Alien invasion in progress!\15\n\n");
  311.         (void) printf("        Type:   <,>     to move the laser base left\15\n");
  312.         (void) printf("                <z>     as above, for lefties\15\n");
  313.         (void) printf("                <.>     to halt the laser base\15\n");
  314.         (void) printf("                <x>     for lefties\15\n");
  315.         (void) printf("                </>     to move the laser base right\15\n");
  316.         (void) printf("                <c>     for lefties\15\n");
  317.         (void) printf("                <space> to fire a laser beam\15\n\n");
  318.         (void) printf("                <1>     to play \"Bloodbath\"\15\n");
  319.         (void) printf("                <2>     to play \"We come in peace\"\15\n");
  320.         (void) printf("                <3>     to play \"The Aliens strike back\"\15\n");
  321.         (void) printf("                <4>     to play \"Invisible Alien Weasels\"\15\n");
  322.         (void) printf("                <5>     to play \"Klinker\"\15\n");
  323.         (void) printf("                <6>     to play \"The Black Hole\"\15\n");
  324.         (void) printf("                <q>     to quit\15\n\n");
  325.         return;
  326. }
  327.  
  328. /*
  329.  * tabl -- tableau draws the starting game tableau.
  330.  */
  331.  
  332. tabl()
  333. {
  334.         clr();
  335.         pos(0,0);
  336.         (void) printf("Level:%2d ",level);
  337.         (void) printf("Score: %-5d ",scores);
  338.         switch (game) {
  339.         case 1:
  340.                 (void) printf("               B L O O D B A T H             ");
  341.                 break;
  342.         case 2:
  343.                 (void) printf("        W E  C O M E  I N  P E A C E !       ");
  344.                 break;
  345.         case 3:
  346.                 (void) printf("T H E   A L I E N S   S T R I K E   B A C K !");
  347.                 break;
  348.         case 4:
  349.                 (void) printf("I N V I S I B L E  A L I E N  W E A S E L S !");
  350.                 break;
  351.         case 5:
  352.                 (void) printf("              K L I N K E R                  ");
  353.                 break;
  354.         case 6:
  355.                 (void) printf("     T H E   B L A C K   H O L E !          ");
  356.                 break;
  357.         }
  358.         pos(0,70);
  359.         if ( game >= 3 ) (void) printf("Bases: %d",bases);
  360.  
  361.         /* initialize alien co-ords, display */
  362.  
  363.         al_cnt = 55;
  364.         danger = level + 11;
  365.         if ( danger > max_danger ) danger = max_danger;
  366.         bmb_max = level + 5;
  367.         if ( bmb_max > BOMB_MAX ) bmb_max = BOMB_MAX;
  368.         spread = level/2;
  369.         for (j=0;j<=4;j++)
  370.         {
  371.                 pos(danger-(2*j),0);
  372.                 for (i=0;i<=10;i++)
  373.                 {
  374.                         ds_obj(((i+j)&1)+(2*(j/2)));
  375.                         (void) printf(" ");
  376.                         al[(11*j)+i].row = danger - (2*j);
  377.                         al[(11*j)+i].col = (6*i);
  378.                 };
  379.         };
  380.         al_num = 54;
  381.         flip = 0;
  382.         flop = 0;
  383.         left = 0;
  384.  
  385.         /* initialize laser base position and velocity */
  386.  
  387.         bas.row = 23;
  388.         bas.col = 72;
  389.         if ( rand() < 10000 ) bas.col = 1;
  390.         bas.vel = 0;
  391.         bem.row = 0;
  392.         if ( game < 6 )
  393.         {
  394.                 pos(bas.row,bas.col);
  395.                 ds_obj(7);
  396.         }
  397.  
  398.         /* initialize bomb arrays (row = 0 implies empty) */
  399.  
  400.         for (i=0;i<bmb_max;i++)   bmb[i].row = 0;
  401.         b = 0;
  402.         bmb_cnt = 0;
  403.  
  404.         /* initialize barricades */
  405.  
  406.         for (i=0;i<=3;i++) {
  407.                 pos(i+19,0);
  408.                 for (j=0;j<80;j++) 
  409.                         if (barr[i][j]=barrinit[i][j])
  410.                                 ds_obj(8);
  411.                         else (void) printf(" ");
  412.         }
  413.  
  414.         /* initialize mystery ships */
  415.  
  416.         shp.vel = 0;
  417.         return;
  418. };
  419.  
  420. /*
  421.  * poll -- read input characters and set global flags
  422.  */
  423.  
  424. poll() {
  425.         int pausing;
  426.         extern unsigned sleep();
  427.  
  428.         pausing = 0;
  429.         (void) ioctl(ttyin, TCSBRK, 1);
  430.         if (game==1) {
  431.                 if (bas.col>=(72-level))  bas.vel = -1;
  432.                 if (bas.col<=1)   bas.vel = 1;
  433.         }
  434.         while ( read(ttyin,combuf,1) != 0 )
  435.         {
  436.                 switch (combuf[0]&0177) {       /* do case char */
  437.                         case LLEFT:     ;
  438.                         case LEFT:      if (game==1)   break;
  439.                                         bas.vel = -1;
  440.                                         break;
  441.                         case LRIGHT:    ;
  442.                         case RIGHT:     if (game==1)   break;
  443.                                         bas.vel = 1;
  444.                                         break;
  445.                         case LHALT:     ;
  446.                         case HALT:      if (game==1)   break;
  447.                                         bas.vel = 0;
  448.                                         break;
  449.                         case FIRE:      if (bem.row==0)   bem.row = 22;
  450.                                         break;
  451.                         case DELETE:    over();
  452.                                         break;
  453.                         case ABORT:     over();
  454.                                         break;
  455.                         case QUIT:      over();
  456.                                         break;
  457.                         case PAUSE:     pausing = 1;
  458.                                         break;
  459.                         case QQUIT:     clr();
  460.                                         (void) ioctl(ttyin,TCSETAF,&ttyorig);
  461.                                         exit(0);
  462.                                         break;
  463.                         case GAME1:     if (game!=0)   break;
  464.                                         game = 1;
  465.                                         break;
  466.                         case GAME2:     if (game!=0)   break;
  467.                                         game = 2;
  468.                                         break;
  469.                         case GAME3:     if (game!=0)   break;
  470.                                         game = 3;
  471.                                         break;
  472.                         case GAME4:     if (game!=0)   break;
  473.                                         game = 4;
  474.                                         break;
  475.                         case GAME5:     if (game!=0)   break;
  476.                                         game = 5;
  477.                                         break;
  478.                         case GAME6:     if (game!=0)    break;
  479.                                         game = 6;
  480.                                         break;
  481.                 }
  482.         }
  483.         if ( pausing == 1 ) (void) sleep(1);
  484.         return;
  485. }
  486.  
  487. /*
  488.  * pos -- positions cursor to a display position.  Row 0 is top-of-screen
  489.  *      row 23 is bottom-of-screen.  The leftmost column is 0; the rightmost
  490.  *      is 79.
  491.  */
  492.  
  493. pos(row,col)
  494. int row,col;
  495. {
  496.         switch ( term_type )
  497.         {
  498.         case VT100:
  499.         case TTY4424:
  500.                 (void) printf("\033[%d;%dH",row+1,col+1);        
  501.                 break;
  502.         case ADM3:
  503.                 (void) printf("\033=%c%c", row + ' ', col + ' ');       
  504.                 break;
  505.         case HP2621:
  506.                 (void) printf("\033&a%dy%dC",row,col);
  507.                 break;
  508.         case Z19:
  509.                 (void) printf("\033Y%c%c", row + ' ', col + ' ');       
  510.         };
  511.         return;
  512. };
  513.  
  514. /*
  515.  * clr -- issues an escape sequence to clear the display
  516.  */
  517.  
  518. clr()
  519. {
  520.         extern unsigned sleep();
  521.  
  522.         switch ( term_type )
  523.         {
  524.         case VT100:
  525.                 (void) printf("\033[2J\033[H"); 
  526.                 break;
  527.         case ADM3:
  528.                 (void) printf("\032");
  529.                 break;
  530.         case HP2621:
  531.                 (void) printf("\033h\033J");
  532.                 break;
  533.         case Z19:
  534.                 (void) printf("\033H\033J");
  535.                 break;
  536.         case TTY4424:
  537.                 (void) printf("\033[H\033J");
  538.                 break;
  539.         };
  540.         (void) sleep(1);
  541.         return;
  542. };
  543.  
  544. /*
  545.  * ds_obj -- display an object
  546.  */
  547.  
  548. ds_obj(class)
  549. int class;
  550. {
  551.         if ((game>=4)&&(class>=0)&&(class<=5))   class = 6;
  552.         switch (class)
  553.         {
  554.         case 0:
  555.                 switch ( term_type )
  556.                 {
  557.                 case VT100:
  558.                         (void) printf(" \033[7mOXO\033[0m ");   
  559.                         break;
  560.                 default:
  561.                         (void) printf(" OXO ");
  562.                         break;
  563.                 };
  564.                 break;
  565.         case 1:
  566.                 switch ( term_type )
  567.                 {
  568.                 case VT100:
  569.                         (void) printf(" \033[7mXOX\033[0m ");   
  570.                         break;
  571.                 default:
  572.                         (void) printf(" XOX ");
  573.                         break;
  574.                 };
  575.                 break;
  576.         case 2:
  577.                 switch ( term_type )
  578.                 {
  579.                 case VT100:
  580.                         (void) printf(" \033[7m\\o/\033[0m ");  
  581.                         break;
  582.                 default:
  583.                         (void) printf(" \\o/ ");
  584.                         break;
  585.                 };
  586.                 break;
  587.         case 3:
  588.                 switch ( term_type )
  589.                 {
  590.                 case VT100:
  591.                         (void) printf(" \033[7m/o\\\033[0m "); 
  592.                         break;
  593.                 default:
  594.                         (void) printf(" /o\\ ");
  595.                         break;
  596.                 };
  597.                 break;
  598.         case 4:
  599.                 switch ( term_type )
  600.                 {
  601.                 case VT100:
  602.                         (void) printf(" \033[7m\"M\"\033[0m "); 
  603.                         break;
  604.                 default:
  605.                         (void) printf(" \"M\" ");
  606.                         break;
  607.                 };
  608.                 break;
  609.         case 5:
  610.                 switch ( term_type )
  611.                 {
  612.                 case VT100:
  613.                         (void) printf(" \033[7mwMw\033[0m ");   
  614.                         break;
  615.                 default:
  616.                         (void) printf(" wMw ");
  617.                         break;
  618.                 };
  619.                 break;
  620.         case 6:
  621.                 (void) printf("     ");
  622.                 break;
  623.         case 7:
  624.                 (void) printf(" xx|xx ");
  625.                 break;
  626.         case 8:
  627.                 if ( game >= 5 ) break;
  628.                 switch ( term_type )
  629.                 {
  630.                 case VT100:
  631.                         (void) printf("\033[7m \033[0m");
  632.                         break;
  633.                 default:
  634.                         (void) printf("#");
  635.                         break;
  636.                 }
  637.                 break;
  638.         };
  639.         return;
  640. };
  641.  
  642. /*
  643.  * base -- move the laser base left or right
  644.  */
  645.  
  646. base()
  647. {
  648.         if ( bas.vel == 0 ) return;
  649.         bas.col += bas.vel;
  650.         if ( bas.col < 1 )
  651.         {
  652.                 bas.col = 1;
  653.                 bas.vel = 0;
  654.         }
  655.         else if ( bas.col > 72 )
  656.         {
  657.                 bas.col = 72;
  658.                 bas.vel = 0;
  659.         }
  660.         if ( game < 6 )
  661.         {
  662.                 pos(bas.row,bas.col);
  663.                 ds_obj(7);
  664.         }
  665. };
  666.  
  667. /*
  668.  * beam -- activate or advance the laser beam if required
  669.  */
  670.  
  671. beam()
  672. {
  673.         int points;
  674.  
  675.         /* display beam */
  676.  
  677.         switch (bem.row) {
  678.                 case 23:
  679.                 case 0:         return;
  680.                 case 21:        pos(21,bem.col);
  681.                         (void) printf("|");
  682.                         break;
  683.                 case 22:bem.col = bas.col + 3;
  684.                         pos(22,bem.col);
  685.                         (void) printf("|");
  686.                         break;
  687.                 default:        pos(bem.row,bem.col);
  688.                         (void) printf("|\10\12\12 ");
  689.                         break;
  690.         }
  691.  
  692.         /* check for contact with an alien */
  693.  
  694.         for (i=0;i<55;i++) {
  695.                 if ((al[i].row==bem.row)&&((al[i].col+1)<=bem.col)
  696.                         &&((al[i].col+3)>=bem.col)) {
  697.  
  698.                         /* contact! */
  699.  
  700.                         points = 1 + (i/22) + (level*(i/11));
  701.                         if (game != 1) points = points - slow;
  702.                         if (points <= 1) points = 1;
  703.                         scores += points;
  704.                         scoreit();
  705.                         pos(bem.row+1,bem.col);
  706.                         (void) printf(" ");
  707.                         if (game >= 4) (void) printf("\07");
  708.                         pos(al[i].row,al[i].col);
  709.                         ds_obj(6);      /* erase beam and alien */
  710.                         bem.row=0;
  711.                         al[i].row=0;    /* clear beam and alien state */
  712.                         al_cnt--;
  713.                         return;
  714.                 }
  715.         }
  716.  
  717.         /* check for contact with a bomb */
  718.  
  719.         for (i=0;i<bmb_max;i++) {
  720.                 if ((bem.row==bmb[i].row)&&(bem.col==bmb[i].col)) {
  721.                         pos(bem.row,bem.col);
  722.                         (void) printf(" \10\12 ");
  723.                         bem.row = 0;
  724.                         bmb_cnt--;
  725.                         bmb[i].row = 0;
  726.                         return;
  727.                 }
  728.         }
  729.  
  730.         /* check for contact with a barricade */
  731.  
  732.         if ((bem.row>=19)&&(bem.row<=22)&&(barr[bem.row-19][bem.col]))
  733.         {
  734.                 pos(bem.row,bem.col);
  735.                 if ( game == 2 )
  736.                         ds_obj(8);
  737.                 else
  738.                 {
  739.                         barr[bem.row-19][bem.col] = 0;
  740.                         (void) printf(" ");
  741.                 }
  742.                 if ( bem.row != 22 )
  743.                         (void) printf("\10\12 ");
  744.                 bem.row = 0;
  745.                 return;
  746.         }
  747.  
  748.         /* check for contact with a mystery ship */
  749.  
  750.         if ((shp.vel!=0)&&(bem.row==1)&&(bem.col>(i=shp.col-shp.vel))&&(bem.col<i+7)) {
  751.  
  752.                 /* contact! */
  753.  
  754.                 pos(1,i);
  755.                 (void) printf(" <BOOM!> \07");
  756.                 pos(1,i);
  757.                 (void) printf("        ");    /* erase ship */
  758.                 shp.vel = 0;
  759.                 scores += shp.val/3;
  760.                 scoreit();
  761.                 pos(2,bem.col);
  762.                 (void) printf(" ");
  763.                 bem.row = 0;
  764.                 return;
  765.         }
  766.  
  767.         /* check for air ball */
  768.  
  769.         if ((--bem.row)==0) {
  770.                 pos(1,bem.col);
  771.                 (void) printf(" \10\12 ");
  772.                 scores -= (level + 1);
  773.                 scoreit();
  774.         }
  775.         return;
  776. };
  777.  
  778. /*
  779.  * bomb -- advance all active bombs
  780.  */
  781.  
  782. bomb() {
  783.         extern unsigned sleep();
  784.  
  785.         for ( b=0; b<bmb_max; b++)
  786.         {
  787.                 if ( bmb_cnt == 0 ) return;
  788.                 if ( bmb[b].row == 0 ) continue;
  789.  
  790.                 /* advance bomb, check for hit and display */
  791.  
  792.                 bmb[b].row++;
  793.                 if (bmb[b].row==23) {
  794.                         if ((bmb[b].col>bas.col)&&
  795.                             (bmb[b].col<=(bas.col+5))) {
  796.  
  797.                                 /* the base is hit! */
  798.  
  799.                                 if ( game > 5 )
  800.                                 {
  801.                                         pos(bas.row,bas.col);
  802.                                         ds_obj(7);
  803.                                 }
  804.                                 bases--;
  805.                                 pos(0,70);
  806.                                 (void) printf("Bases: %d",bases);
  807.                                 scores -= DEATH;
  808.                                 scoreit();
  809.                                 if (bases==0) {
  810.                                         over(); /* game is over */
  811.                                 }
  812.                                 (void) sleep(2);
  813.                                 pos(23,bas.col);
  814.                                 (void) printf("       ");
  815.                                 bas.col = 72;
  816.                                 if ( rand() < 13000 ) bas.col = 1;
  817.                                 if ( game < 6 )
  818.                                 {
  819.                                         pos(23,bas.col);
  820.                                         ds_obj(7);
  821.                                 }
  822.                         }
  823.                 }
  824.                 if((bmb[b].row>=19)&&(bmb[b].row<23)&&(barr[bmb[b].row-19][bmb[b].col])) {
  825.  
  826.                         /* the bomb has hit a barricade */
  827.  
  828.                         pos(bmb[b].row-1,bmb[b].col);
  829.                         (void) printf(" \10\12 ");
  830.                         barr[bmb[b].row-19][bmb[b].col] = 0;
  831.                         bmb[b].row = 0;
  832.                         bmb_cnt--;
  833.                         continue;
  834.                 }
  835.                 pos(bmb[b].row-1,bmb[b].col);
  836.                 (void) printf(" ");
  837.                 if (bmb[b].row==23) {
  838.                         bmb_cnt--;
  839.                         bmb[b].row = 0;
  840.                 }
  841.                 else
  842.                         (void) printf("\10\12*");
  843.         }
  844. }
  845.  
  846. /*
  847.  * ship -- create or advance a mystery ship if desired
  848.  */
  849.  
  850. ship() {
  851.         int vs_cols = 80;
  852.         if (shp.vel==0) {
  853.                 if ((i=rand())<96) {
  854.                         /* create a mystery ship */
  855.                         if (i<48) {
  856.                                 shp.vel = 1;
  857.                                 shp.col = MINCOL;
  858.                         }
  859.                         else {
  860.                                 shp.vel = -1;
  861.                                 shp.col = vs_cols - 8;
  862.                         }
  863.                         shp.val=90;
  864.                 }
  865.         }
  866.         else {
  867.  
  868.                 /* update existing mystery ship */
  869.  
  870.                 pos(1,shp.col);
  871.                 if (game<=3)  (void) printf("  <=%d=>  ",shp.val/3);
  872.                 shp.val--;
  873.                 shp.col += shp.vel;
  874.                 if (((i=shp.col)>(vs_cols-8))||(i<MINCOL)) {
  875.  
  876.                         /* remove ship */
  877.  
  878.                         pos(1,shp.col-shp.vel);
  879.                         (void) printf("        ");
  880.                         shp.vel = 0;
  881.                 }
  882.         }
  883. }
  884.  
  885. /*
  886.  * alien -- advance the next alien
  887.  */
  888.  
  889. alien()
  890. {
  891.         while (1)
  892.         {
  893.                 if ((al_num = al_num + 1) >= 55)
  894.                 {
  895.                         if (al_cnt==0)   return; /* check if done */
  896.                         flop = 0;
  897.                         if (flip) { left = 1 - left;
  898.                                 flop = 1;
  899.                                 flip = 0;
  900.                         }
  901.                         al_num = 0;
  902.                 }
  903.                 if ((i = al[al_num].row)>0)   break;
  904.         }
  905.         if (i>=23)
  906.         {
  907.  
  908.                 /* game over, aliens have overrun base */
  909.  
  910.                 scores -= OVERUN;
  911.                 scoreit();
  912.                 over();
  913.         }
  914.  
  915.         if (left)   al[al_num].col--;
  916.         else   al[al_num].col++;
  917.         if (((j = al[al_num].col)==0)||(j>=(75-slow-((3*level)/2))))   flip = 1;
  918.         pos(i,j);
  919.         if (flop) {
  920.                 ds_obj(6);
  921.                 i = ++al[al_num].row;
  922.                 pos(i,j);
  923.         }
  924.         ds_obj(((j+(i/2))&1) + (2*(al_num/22)));
  925.  
  926.         /* check for contact with a barricade */
  927.  
  928.         if ((al[al_num].row>=19)&&(al[al_num].row<23))
  929.         {
  930.                 j=al[al_num].col;
  931.                 for (i=3;(i>=-1)&&(j+i>=0);i--)
  932.                         barr[al[al_num].row-19][al[al_num].col+i] = 0;
  933.         }
  934.  
  935.         /* check for bomb release */
  936.  
  937.         if ((game==1)||(game==2))   return;
  938.         for (i=al_num-11;i>=0;i -= 11) {
  939.                 if (al[i].row!=0)   return;
  940.         }
  941.         if ( (al[al_num].col >= (bas.col-spread) ) &&
  942.              (al[al_num].col <  (bas.col+3+spread) ) &&
  943.            (al[al_num].row<=BOMB_ROW)) {
  944.                 for (i=0;i<bmb_max;i++) {
  945.                         if (bmb[i].row==0) {
  946.                                 bmb[i].row = al[al_num].row;
  947.                                 bmb[i].col = al[al_num].col + 2;
  948.                                 bmb_cnt++;
  949.                                 break;
  950.                         }
  951.                 }
  952.         }
  953.         return;
  954. };
  955.  
  956. /*
  957.  * scoreit -- print current point total
  958.  */
  959.  
  960. scoreit()
  961. {
  962.         pos(0,16);
  963.         (void) printf("%d  ",scores);
  964.         return;
  965. }
  966.  
  967. /*
  968.  * gauntlet -- challenge player to tougher game
  969.  */
  970.  
  971. gauntlet()
  972. {
  973.         extern unsigned sleep();
  974.         char *epithet();
  975.  
  976.         clr();
  977.         pos(10,10);
  978.         (void) printf("Congratulations %s ",epithet());
  979.         (void) printf("- you have won at level %d",level++);
  980.         pos(12,10);
  981.         (void) printf("Now let's see how good you are at level %d",level);
  982.         (void) sleep(5);
  983. }
  984.  
  985. /*
  986.  * epithet -- choose name for player based upon level
  987.  */
  988.  
  989. char *epithet()
  990. {
  991.         static char *name[]={
  992.                 "rookie",
  993.                 "earthling",
  994.                 "space cadet",
  995.                 "yeoman",
  996.                 "lieutenant",
  997.                 "commander",
  998.                 "captain",
  999.                 "admiral",
  1000.                 "master assassin"
  1001. };
  1002.  
  1003.         return((level > 8) ? name[8] : name[level] );
  1004. }
  1005.  
  1006. /*
  1007.  * over -- game over processing
  1008.  */
  1009.  
  1010. over() {
  1011.         int savgam;
  1012.         extern unsigned sleep();
  1013.  
  1014.         /* display the barricades if they were invisible */
  1015.  
  1016.         if ( game >= 5 )
  1017.         {
  1018.                 savgam = game;
  1019.                 game = 3;
  1020.                 for ( i=0; i<=3; i++)
  1021.                 {
  1022.                         pos(i+19,0);
  1023.                         for ( j=0; j<80; j++)
  1024.                                 if ( barr[i][j] == 1 )
  1025.                                         ds_obj(8);
  1026.                                 else
  1027.                                         (void) printf(" ");
  1028.                 }
  1029.                 game = savgam;
  1030.         }
  1031.                 
  1032.         /* display the aliens if they were invisible */
  1033.  
  1034.         if (game>=4) {
  1035.                 savgam = game;
  1036.                 game = 3;       /* remove the cloak of invisibility */
  1037.                 for (i=0;i<55;i++)   if (al[i].row!=0) {
  1038.                         pos(al[i].row,al[i].col);
  1039.                         ds_obj(((al[i].col+(al[i].row/2))&1) + (2*(i/22)));
  1040.                 }
  1041.                 game = savgam;
  1042.                 (void) sleep(5);
  1043.         }
  1044.  
  1045.         /* reset tty */
  1046.  
  1047.         (void) ioctl(ttyin,TCSETAF,&ttyorig);
  1048.         
  1049.         /* final output */
  1050.  
  1051.         loggame();
  1052.         clr();
  1053.         alhs();
  1054. }
  1055.  
  1056. /*
  1057.  * loggame -- enter users score into log file
  1058.  */
  1059.  
  1060. loggame()
  1061. {
  1062.         char *ptr;
  1063.         char *ctime();
  1064.         long dummy = 0;
  1065.         long time();
  1066.         struct passwd *getpwuid(), *p;
  1067.         char uname[10];
  1068.         extern char *strcpy();
  1069.         FILE *logfile;
  1070.  
  1071.         if ( (logfile = fopen(LOGFILE,"a")) != NULL )
  1072.         {
  1073.                 dummy = time(&dummy);
  1074.                 ptr = ctime(&dummy);
  1075.                 if ( (p = getpwuid(getuid())) == NULL )
  1076.                         return;
  1077.                 (void) strcpy(uname,p->pw_name);
  1078.                 (void) fprintf(logfile,"%.24s %s\t%2u\t%2u\t%d\n",
  1079.                         ptr,uname,game,level,scores);
  1080.         }
  1081.         return;
  1082. }
  1083.  
  1084. /*
  1085.  * alhs -- print alien high scores
  1086.  */
  1087.  
  1088. alhs()
  1089. {
  1090.         struct passwd *getpwuid(), *p;
  1091.         char hnam[10];
  1092.         extern long lseek();
  1093.         extern char *strcpy();
  1094.         
  1095.         if ((scorefile=open(SCOREFILE,O_RDWR)) == -1)
  1096.         {
  1097.                 (void) printf("aliens: can't open the scorefile\n");
  1098.                 exit(1);
  1099.         }
  1100.         (void) printf("Game type\t\tHigh Scores\t\tPlayer");
  1101.         (void) read( scorefile, (char *) scorsave, SCORESIZE);
  1102.         (void) printf("\n");
  1103.  
  1104.         /* high score to date processing */
  1105.  
  1106.         if (scorsave[game-1].hscr < scores) {
  1107.                 scorsave[game-1].sscr = scorsave[game-1].hscr;
  1108.                 scorsave[game-1].sid = scorsave[game-1].hid;
  1109.                 scorsave[game-1].hscr = scores;
  1110.                 scorsave[game-1].hid = getuid();
  1111.                 (void) lseek(scorefile,0l,0);
  1112.                 (void) write(scorefile, (char *) scorsave,SCORESIZE);
  1113.                 scores=0;
  1114.         }
  1115.         else if (scorsave[game-1].sscr < scores)
  1116.         {
  1117.                 scorsave[game-1].sscr = scores;
  1118.                 scorsave[game-1].sid = getuid();
  1119.                 (void) lseek(scorefile,0l,0);
  1120.                 (void) write(scorefile, (char *) scorsave,SCORESIZE);
  1121.                 scores=0;
  1122.         }
  1123.  
  1124.         /* print high scores for all games */
  1125.  
  1126.         for ( i=0; i<6; i++)
  1127.         {
  1128.                 (void) printf("%5u",i+1);
  1129.                 (void) printf("\t\t\t%7lu",scorsave[i].hscr);
  1130.                 if ( (p = getpwuid(scorsave[i].hid)) == NULL )
  1131.                         (void) printf("\t\t\t ???\n");
  1132.                 else
  1133.                 {
  1134.                         (void) strcpy(hnam,p->pw_name);
  1135.                         (void) printf("\t\t\t%4s",hnam);
  1136.                         (void) printf("\n");
  1137.                 }
  1138.                 (void) printf("\t\t\t%7lu",scorsave[i].sscr);
  1139.                 if ( (p = getpwuid(scorsave[i].sid)) == NULL )
  1140.                         (void) printf("\t\t\t ???\n");
  1141.                 else
  1142.                 {
  1143.                         (void) strcpy(hnam,p->pw_name);
  1144.                         (void) printf("\t\t\t%4s",hnam);
  1145.                         (void) printf("\n");
  1146.                 }
  1147.  
  1148.                 /* print users score if not high score */
  1149.  
  1150.                 if ( (game==(i+1)) && (scores != 0) )
  1151.                 {
  1152.                         (void) printf("\t\t\t%7d",scores);
  1153.                         (void) printf("\t\t\t you\n");
  1154.                 }
  1155.                 (void) printf("\n");
  1156.         }
  1157.         (void) close(scorefile);
  1158.         exit(0);
  1159. }
  1160.